package com.dragon.concurrent.demo.book;

import java.util.concurrent.TimeUnit;

public class ProduceConsumeDemo {

    /**
     * 定义产品初始值 product ： 0
     */
    private static int product = 0;

    /**
     * 是否已经生产，默认为 false
     */
    private static boolean isProduced = false;

    /**
     * 生产的最大产量
     */
    private static final int MAX_OUT_PUT = 500;

    /**
     * 定义监视器
     */
    private static final Object LOCK = new Object();

    public void produce() throws InterruptedException {
        while (true) {
            synchronized (LOCK) {
                while (isProduced) {
                    LOCK.wait();
                }
                if (product < MAX_OUT_PUT) {
                    System.out.println(Thread.currentThread().getName() + " produce the product " + ++product);
                    isProduced = true;
                    LOCK.notifyAll();
                }
            }
        }
    }

    public void consume() throws InterruptedException {
        while (true) {
            synchronized (LOCK) {
                while (!isProduced) {
                    LOCK.wait();
                }
                if (product < MAX_OUT_PUT) {
                    System.out.println(Thread.currentThread().getName() + " consume the product " + product);
                    isProduced = false;
                    LOCK.notifyAll();
                }
            }
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ProduceConsumeDemo produceConsumeDemo = new ProduceConsumeDemo();
        for (int i = 0; i < 2; i++) {
            Thread thread = new Thread(() -> {
                try {
                    produceConsumeDemo.produce();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "produceThread[" + i + "]");
            thread.setDaemon(true);
            thread.start();
        }

        for (int i = 0; i < 3; i++) {
            Thread thread = new Thread(() -> {
                try {
                    produceConsumeDemo.consume();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }, "consumeThread[" + i + "}");
            thread.setDaemon(true);
            thread.start();
        }

        TimeUnit.SECONDS.sleep(10L);
        System.out.println("main thread finished");
    }

}
